package com.syh.jn.scm.domain.supplier.entity.stock;

import cn.redscarf.commons.spring.SpringContextUtils;
import cn.redscarf.commons.wrapper.Restrictions;
import cn.redscarf.commons.wrapper.Wrapper;
import cn.redscarf.commons.wrapper.expression.orderExpression.Order;
import com.syh.core.ddd.domain.AbstractSimpleAggregate;
import com.syh.jn.scm.domain.supplier.entity.base.upstream.Upstream;
import com.syh.jn.scm.domain.supplier.entity.logistics.LogisticsBill;
import com.syh.jn.scm.domain.supplier.entity.logistics.LogisticsBillItem;
import com.syh.jn.scm.domain.supplier.entity.purchase.PurchaseOrder;
import com.syh.jn.scm.domain.supplier.entity.purchase.PurchaseOrderItem;
import com.syh.jn.scm.domain.supplier.entity.purchase.PurchaseReturnOrder;
import com.syh.jn.scm.domain.supplier.entity.sale.SaleOrder;
import com.syh.jn.scm.domain.supplier.entity.sale.SaleReturnOrder;
import com.syh.jn.scm.domain.supplier.repository.base.goods.GoodsRepository;
import com.syh.jn.scm.domain.supplier.repository.base.upstream.UpstreamReadRepository;
import com.syh.jn.scm.domain.supplier.repository.base.upstream.UpstreamRepository;
import com.syh.jn.scm.domain.supplier.repository.logistics.LogisticsBillReadRepository;
import com.syh.jn.scm.domain.supplier.repository.logistics.LogisticsBillRepository;
import com.syh.jn.scm.domain.supplier.repository.purchase.PurchaseOrderReadRepository;
import com.syh.jn.scm.domain.supplier.repository.purchase.PurchaseOrderRepository;
import com.syh.jn.scm.domain.supplier.repository.purchase.PurchaseReturnOrderRepository;
import com.syh.jn.scm.domain.supplier.repository.sale.SaleOrderRepository;
import com.syh.jn.scm.domain.supplier.repository.sale.SaleReturnOrderRepository;
import com.syh.jn.scm.domain.supplier.repository.stock.StockGoodsReadRepository;
import com.syh.jn.scm.domain.supplier.repository.stock.StockRecordReadRepository;
import com.syh.jn.scm.dto.supplier.base.goods.GoodsVo;
import com.syh.jn.scm.dto.supplier.stock.StockRecordItemVo;
import com.syh.jn.scm.dto.supplier.stock.StockRecordVo;
import com.syh.jn.scm.exception.BusinessException;
import com.syh.jn.scm.infrastructure.repository.impl.supplier.stock.StockRecordReadRepositoryMbImpl;
import com.syh.jn.scm.service.api.supplier.stock.enums.StockGoodsRecordEnums;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 出入库记录子项
 */
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
public class StockRecordItem extends AbstractSimpleAggregate<Long> {

    //需要记录出库时的库存成本时使用的构造器
    public StockRecordItem(LogisticsBill bill, LogisticsBillItem billItem, Short dataType) {
        GoodsRepository goodsReadRepository = (GoodsRepository) SpringContextUtils.getBean(GoodsRepository.class);
        GoodsVo goods = goodsReadRepository.getKeyView(billItem.getGoodsId());

        this.goodsId = billItem.getGoodsId();
        this.goodsName = billItem.getGoodsName();
        this.goodsCode = billItem.getGoodsCode();
        this.categoryCatalogCode = goods.getCategoryCatalogCode();
        this.categoryId = goods.getCategoryId();
        this.categoryName = goods.getCategoryName();
        this.goodsBrandId = goods.getGoodsBrandId();
        this.goodsBrandName = goods.getGoodsBrandName();
        this.orderItemId = billItem.getOrderItemId();
        this.units = billItem.getUnits();
        this.specName = goods.getSpecName();
        this.conversionRate = goods.getConversionRate();
        this.salesTaxRate = goods.getSalesTaxRate();

        switch (bill.getOrderType()) {
            case 0://销售订单：记录出库的库存成本
                this.orderType = StockGoodsRecordEnums.Type.SALE_ORDER.getStatus();
                if (dataType.equals(StockGoodsRecordEnums.DataType.NORMAL.getStatus())) {
                    //如果物流主单id不为空 则是直采直销发货 直接获取采购单发货价格
                    if (bill.getSubjectBillId() != null) {
                        //获取采购物流单
                        LogisticsBillReadRepository logisticsBillReadRepository = (LogisticsBillReadRepository) SpringContextUtils.getBean(LogisticsBillRepository.class);
                        LogisticsBill subjectBill = logisticsBillReadRepository.getById(bill.getSubjectBillId());
                        //获取采购单项
                        PurchaseOrderReadRepository purchaseOrderReadRepository = (PurchaseOrderReadRepository) SpringContextUtils.getBean("purchaseOrderRepositoryImpl");
                        PurchaseOrder purchaseOrder = purchaseOrderReadRepository.getById(subjectBill.getOrderId());
                        if (!purchaseOrder.getSalesOrderId().equals(bill.getOrderId())) {
                            throw new BusinessException("数据异常，采购单与销售单id不匹配");
                        }
                        UpstreamReadRepository upstreamReadRepository = (UpstreamReadRepository) SpringContextUtils.getBean(UpstreamRepository.class);
                        Upstream upstream = upstreamReadRepository.getById(purchaseOrder.getUpStreamCompanyId());
                        this.taxpayer = upstream.getTaxpayer();
                        for (PurchaseOrderItem purchaseOrderItem: purchaseOrder.getItems()) {
                            if (purchaseOrderItem.getSaleOrderItemId().equals(billItem.getOrderItemId())) {
                                this.price =purchaseOrderItem.getPrice();
                                this.quantity = billItem.getQuantity().negate();
                                break;
                            }
                        }
                     //普通销售直接获取库存平均成本
                    } else {
                        StockGoodsReadRepository stockGoodsRepository = (StockGoodsReadRepository) SpringContextUtils.getBean(StockGoodsReadRepository.class);
                        Wrapper we = Wrapper.build();
                        we.append(Restrictions.eq("businessEntityId", bill.getBusinessEntityId()));
                        we.append(Restrictions.eq("storehouseId", bill.getDepotId()));
                        we.append(Restrictions.eq("goodsId", this.goodsId));
                        StockGoods stockGoods = stockGoodsRepository.getOne(we);
                        this.price = stockGoods.getAverageCost();
                        this.quantity = billItem.getQuantity().negate();
                    }
                } else {
                    this.price = this.getPriceBeforeRollback(bill);
                    this.quantity = billItem.getQuantity();
                }
                break;
            case 3://采购退货订单：记录出库的库存成本
                this.orderType = StockGoodsRecordEnums.Type.PURCHASE_RETURN_ORDER.getStatus();
                if (dataType.equals(StockGoodsRecordEnums.DataType.NORMAL.getStatus())) {
                    PurchaseReturnOrderRepository purchaseRetRead = (PurchaseReturnOrderRepository) SpringContextUtils.getBean(PurchaseReturnOrderRepository.class);
                    PurchaseReturnOrder purRetOrder = purchaseRetRead.getById(bill.getOrderId());

                    PurchaseOrderRepository purchaseRead = (PurchaseOrderRepository) SpringContextUtils.getBean("purchaseOrderRepositoryImpl");
                    PurchaseOrder purOrder = purchaseRead.getById(purRetOrder.getPurchaseOrderId());

                    //TODO 存在多次采购入库时取所有有效入库记录的价格平均
                    StockRecordReadRepositoryMbImpl recordRead = (StockRecordReadRepositoryMbImpl) SpringContextUtils.getBean(StockRecordReadRepositoryMbImpl.class);
                    Wrapper we = Wrapper.build();
                    we.append(Restrictions.eq("originalOrderId", purOrder.getId()));
                    we.append(Restrictions.eq("type", StockGoodsRecordEnums.Type.PURCHASE_ORDER.getStatus()));
                    we.order(Order.asc("createTimeStamp"));
                    List<StockRecordVo> recordVos = recordRead.getList(we);

                    if (recordVos == null || recordVos.isEmpty())
                        throw new BusinessException("数据异常，该采购订单没有入库记录");
                    //找出有效入库记录
                    Map<Long, Integer> countMap = new HashMap<>();
                    Map<Long, Long> recordIdMap = new HashMap<>();
                    for (StockRecordVo vo : recordVos) {
                        if (!countMap.containsKey(vo.getOriginalLogisticsId()))
                            countMap.put(vo.getOriginalLogisticsId(), 0);
                        if (vo.getDataType().equals(StockGoodsRecordEnums.DataType.NORMAL.getStatus())) {
                            Integer count = countMap.get(vo.getOriginalLogisticsId());
                            countMap.put(vo.getOriginalLogisticsId(), ++count);
                            recordIdMap.put(vo.getOriginalLogisticsId(), vo.getId());
                        } else {
                            Integer count = countMap.get(vo.getOriginalLogisticsId());
                            countMap.put(vo.getOriginalLogisticsId(), --count);
                            if (count < 1) {
                                recordIdMap.remove(vo.getOriginalLogisticsId());
                            }
                        }
                    }
                    //取所有销售出库商品的价格平均
                    BigDecimal goodsTotalNum = BigDecimal.ZERO;
                    BigDecimal goodsTotalAmt = BigDecimal.ZERO;
                    for (Long recordId : recordIdMap.values()) {
                        List<StockRecordItemVo> items = recordRead.findStockRecordItemsByStockRecordId(recordId);
                        //获取销售订单的出库时生成的库存记录中的商品成本（多个相同商品取平均值）
                        for (StockRecordItemVo item : items) {
                            if (item.getGoodsId().equals(billItem.getGoodsId())) {
                                goodsTotalNum = goodsTotalNum.add(item.getQuantity());
                                goodsTotalAmt = goodsTotalAmt.add(item.getPrice().multiply(item.getQuantity()).setScale(6, BigDecimal.ROUND_HALF_UP));
                            }
                        }
                    }
                    BigDecimal goodsAvgPrice = BigDecimal.ZERO;
                    if (goodsTotalNum.compareTo(BigDecimal.ZERO) > 0) {
                        goodsAvgPrice = goodsAvgPrice.add(goodsTotalAmt.divide(goodsTotalNum, 6, BigDecimal.ROUND_HALF_UP));
                    }
                    this.price = goodsAvgPrice;
                    this.quantity = billItem.getQuantity().negate();
                } else {
                    this.price = this.getPriceBeforeRollback(bill);
                    this.quantity = billItem.getQuantity();
                }
                break;
            case 1://销售退货订单：记录入库时的商品单价
                this.orderType = StockGoodsRecordEnums.Type.SALE_RETURN_ORDER.getStatus();
                if (dataType.equals(StockGoodsRecordEnums.DataType.NORMAL.getStatus())) {
                    SaleReturnOrderRepository saleRetRead = (SaleReturnOrderRepository) SpringContextUtils.getBean(SaleReturnOrderRepository.class);
                    SaleReturnOrder saleRetOrder = saleRetRead.getById(bill.getOrderId());

                    SaleOrderRepository saleRead = (SaleOrderRepository) SpringContextUtils.getBean("saleOrderRepositoryImpl");
                    SaleOrder saleOrder = saleRead.getById(saleRetOrder.getSaleOrderId());

                    //TODO 存在多次销售发货时取所有有效出库记录的价格平均
                    StockRecordReadRepositoryMbImpl recordRead = (StockRecordReadRepositoryMbImpl) SpringContextUtils.getBean(StockRecordReadRepositoryMbImpl.class);
                    Wrapper we = Wrapper.build();
                    we.append(Restrictions.eq("originalOrderId", saleOrder.getId()));
                    we.append(Restrictions.eq("type", StockGoodsRecordEnums.Type.SALE_ORDER.getStatus()));
                    we.order(Order.asc("createTimeStamp"));
                    List<StockRecordVo> recordVos = recordRead.getList(we);

                    if (recordVos == null || recordVos.isEmpty())
                        throw new BusinessException("数据异常，该销售订单没有出库记录");
                    //找出有效出库记录
                    Map<Long, Integer> countMap = new HashMap<>();
                    Map<Long, Long> recordIdMap = new HashMap<>();
                    for (StockRecordVo vo : recordVos) {
                        if (!countMap.containsKey(vo.getOriginalLogisticsId()))
                            countMap.put(vo.getOriginalLogisticsId(), 0);
                        if (vo.getDataType().equals(StockGoodsRecordEnums.DataType.NORMAL.getStatus())) {
                            Integer count = countMap.get(vo.getOriginalLogisticsId());
                            countMap.put(vo.getOriginalLogisticsId(), ++count);
                            recordIdMap.put(vo.getOriginalLogisticsId(), vo.getId());
                        } else {
                            Integer count = countMap.get(vo.getOriginalLogisticsId());
                            countMap.put(vo.getOriginalLogisticsId(), --count);
                            if (count < 1) {
                                recordIdMap.remove(vo.getOriginalLogisticsId());
                            }
                        }
                    }
                    //取所有销售出库商品的价格平均
                    BigDecimal goodsTotalNum = BigDecimal.ZERO;
                    BigDecimal goodsTotalAmt = BigDecimal.ZERO;
                    for (Long recordId : recordIdMap.values()) {
                        List<StockRecordItemVo> items = recordRead.findStockRecordItemsByStockRecordId(recordId);
                        //获取销售订单的出库时生成的库存记录中的商品成本（多个相同商品取平均值）
                        for (StockRecordItemVo item : items) {
                            if (item.getGoodsId().equals(billItem.getGoodsId())) {
                                goodsTotalNum = goodsTotalNum.add(item.getQuantity());
                                goodsTotalAmt = goodsTotalAmt.add(item.getPrice().multiply(item.getQuantity()).setScale(6, BigDecimal.ROUND_HALF_UP));
                            }
                        }
                    }
                    BigDecimal goodsAvgPrice = BigDecimal.ZERO;
                    if (goodsTotalNum.compareTo(BigDecimal.ZERO) != 0) {
                        goodsAvgPrice = goodsAvgPrice.add(goodsTotalAmt.divide(goodsTotalNum, 6, BigDecimal.ROUND_HALF_UP));
                    }
                    this.price = goodsAvgPrice;
                    this.quantity = billItem.getQuantity();
                } else {
                    this.price = this.getPriceBeforeRollback(bill);
                    this.quantity = billItem.getQuantity().negate();
                }
                break;
            case 2://采购订单
                this.orderType = StockGoodsRecordEnums.Type.PURCHASE_ORDER.getStatus();
                if (dataType.equals(StockGoodsRecordEnums.DataType.NORMAL.getStatus())) {
                    PurchaseOrderRepository purchaseRead = (PurchaseOrderRepository) SpringContextUtils.getBean("purchaseOrderRepositoryImpl");
                    PurchaseOrderItem orderItem = purchaseRead.getItemByItemId(this.orderItemId);
                    this.price = orderItem.getPrice();
                    this.quantity = billItem.getQuantity();
                } else {
                    this.price = this.getPriceBeforeRollback(bill);
                    this.quantity = billItem.getQuantity().negate();
                }
                break;
        }
    }

    public StockRecordItem(StockLossItem stockLossItem, Short dataType) {
        this.goodsId = stockLossItem.getGoodsId();
        this.goodsName = stockLossItem.getGoodsName();
        this.goodsCode = stockLossItem.getCode();
        this.categoryCatalogCode = stockLossItem.getCategoryCatalogCode();
        this.categoryId = stockLossItem.getCategoryId();
        this.categoryName = stockLossItem.getCategoryName();
        this.orderItemId = stockLossItem.getId();
        this.orderType = StockGoodsRecordEnums.Type.STOCK_LOSS_BILL.getStatus();
        if (dataType.equals(StockGoodsRecordEnums.DataType.NORMAL.getStatus())) {
            //获取库存商品平均成本
            StockGoodsReadRepository stockGoodsReadRepository = (StockGoodsReadRepository) SpringContextUtils.getBean(StockGoodsReadRepository.class);
            StockGoods stockGoods = stockGoodsReadRepository.getById(stockLossItem.getStockGoodsId());
            this.price = stockGoods.getAverageCost();
            this.quantity = stockLossItem.getQuantity().negate();
        } else {
            this.quantity = stockLossItem.getQuantity();
            this.price = this.getPriceBeforeRollbackToOtherRecord(stockLossItem.getLossOrderId(), stockLossItem.getId(), StockGoodsRecordEnums.Type.STOCK_LOSS_BILL.getStatus());
        }
        this.units = stockLossItem.getUnits();
        this.specName = stockLossItem.getSpecName();
        this.conversionRate = stockLossItem.getConversionRate();
    }

    public StockRecordItem(StockSpillItem stockSpillItem, Short dataType) {
        this.goodsId = stockSpillItem.getGoodsId();
        this.goodsName = stockSpillItem.getGoodsName();
        this.goodsCode = stockSpillItem.getCode();
        this.categoryCatalogCode = stockSpillItem.getCategoryCatalogCode();
        this.categoryId = stockSpillItem.getCategoryId();
        this.categoryName = stockSpillItem.getCategoryName();
        this.orderType = StockGoodsRecordEnums.Type.STOCK_SPILL_BILL.getStatus();
        if (dataType.equals(StockGoodsRecordEnums.DataType.NORMAL.getStatus())) {
            this.quantity = stockSpillItem.getQuantity();
            //获取库存商品平均成本
            StockGoodsReadRepository stockGoodsReadRepository = (StockGoodsReadRepository) SpringContextUtils.getBean(StockGoodsReadRepository.class);
            StockGoods stockGoods = stockGoodsReadRepository.getById(stockSpillItem.getStockGoodsId());
            this.price = stockGoods.getAverageCost();
        } else {
            this.quantity = stockSpillItem.getQuantity().negate();
            this.price = this.getPriceBeforeRollbackToOtherRecord(stockSpillItem.getSpillId(), stockSpillItem.getId(), StockGoodsRecordEnums.Type.STOCK_SPILL_BILL.getStatus());
        }
        this.orderItemId = stockSpillItem.getId();
        this.units = stockSpillItem.getUnits();
        this.specName = stockSpillItem.getSpecName();
        this.conversionRate = stockSpillItem.getConversionRate();
    }

    public StockRecordItem(StockOtherInBillItem stockOtherInBillItem, Short dataType) {
        this.goodsId = stockOtherInBillItem.getGoodsId();
        this.goodsName = stockOtherInBillItem.getGoodsName();
        this.goodsCode = stockOtherInBillItem.getCode();
        this.categoryCatalogCode = stockOtherInBillItem.getCategoryCatalogCode();
        this.categoryId = stockOtherInBillItem.getCategoryId();
        this.categoryName = stockOtherInBillItem.getCategoryName();
        this.orderType = StockGoodsRecordEnums.Type.STOCK_OTHER_IN_BILL.getStatus();
        if (dataType.equals(StockGoodsRecordEnums.DataType.NORMAL.getStatus())) {
            this.quantity = stockOtherInBillItem.getQuantity();
        } else {
            this.quantity = stockOtherInBillItem.getQuantity().negate();
        }
        this.orderItemId = stockOtherInBillItem.getId();
        this.price = stockOtherInBillItem.getPrice();

        this.units = stockOtherInBillItem.getUnits();
        this.specName = stockOtherInBillItem.getSpecName();
        this.conversionRate = stockOtherInBillItem.getConversionRate();
    }

    public StockRecordItem(StockOtherOutBillItem stockOtherOutBillItem,Long storehouseId, Short dataType) {
        this.goodsId = stockOtherOutBillItem.getGoodsId();
        this.goodsName = stockOtherOutBillItem.getGoodsName();
        this.goodsCode = stockOtherOutBillItem.getCode();
        this.categoryCatalogCode = stockOtherOutBillItem.getCategoryCatalogCode();
        this.categoryId = stockOtherOutBillItem.getCategoryId();
        this.categoryName = stockOtherOutBillItem.getCategoryName();

        this.orderType = StockGoodsRecordEnums.Type.STOCK_OTHER_OUT_BILL.getStatus();
        if (dataType.equals(StockGoodsRecordEnums.DataType.NORMAL.getStatus())) {
            this.quantity = stockOtherOutBillItem.getQuantity().negate();
            //获取库存商品平均成本
            StockGoodsReadRepository stockGoodsReadRepository = (StockGoodsReadRepository) SpringContextUtils.getBean(StockGoodsReadRepository.class);
            StockGoods stockGoods = stockGoodsReadRepository.getByStorehouseIdAndGoodsId(storehouseId,stockOtherOutBillItem.getGoodsId());
            this.price = stockGoods.getAverageCost();
        } else {
            this.quantity = stockOtherOutBillItem.getQuantity();
            this.price = this.getPriceBeforeRollbackToOtherRecord(stockOtherOutBillItem.getStockOtherOutBillId(), stockOtherOutBillItem.getId(), this.orderType);
        }
        this.orderItemId = stockOtherOutBillItem.getId();

        this.units = stockOtherOutBillItem.getUnits();
        this.specName = stockOtherOutBillItem.getSpecName();
        this.conversionRate = stockOtherOutBillItem.getConversionRate();
    }

    private BigDecimal getPriceBeforeRollback(LogisticsBill bill) {
        StockRecordReadRepositoryMbImpl recordRead = (StockRecordReadRepositoryMbImpl) SpringContextUtils.getBean(StockRecordReadRepositoryMbImpl.class);
        Wrapper we = Wrapper.build();
        we.append(Restrictions.eq("originalLogisticsId", bill.getId()));
        we.append(Restrictions.eq("storehouseId", bill.getDepotId()));
        we.append(Restrictions.eq("type", this.orderType));
        we.order(Order.desc("createTimeStamp"));
        StockRecordVo recordVo = recordRead.getOne(we);
        if (!recordVo.getDataType().equals(StockGoodsRecordEnums.DataType.NORMAL.getStatus()))
            throw new BusinessException("回滚失败，出入库记录异常！");

        //多个相同商品取价格平均
        BigDecimal goodsTotalNum = BigDecimal.ZERO;
        BigDecimal goodsTotalAmt = BigDecimal.ZERO;
        for (StockRecordItemVo item : recordVo.getItemsVo()) {
            if (item.getGoodsId().equals(this.goodsId)) {
                goodsTotalNum = goodsTotalNum.add(item.getQuantity());
                goodsTotalAmt = goodsTotalAmt.add(item.getPrice().multiply(item.getQuantity()).setScale(2, BigDecimal.ROUND_HALF_UP));
            }
        }
        BigDecimal goodsAvgPrice = BigDecimal.ZERO;
        if (goodsTotalNum.compareTo(BigDecimal.ZERO) != 0) {
            goodsAvgPrice = goodsAvgPrice.add(goodsTotalAmt.divide(goodsTotalNum, 6, BigDecimal.ROUND_HALF_UP));
        }

        return goodsAvgPrice;
    }

    private BigDecimal getPriceBeforeRollbackToOtherRecord(Long orderId,Long orderItemId, Short orderType) {
        StockRecordReadRepository stockRecordReadRepository = (StockRecordReadRepository) SpringContextUtils.getBean("stockRecordRepositoryImpl");
        Wrapper wrapper = Wrapper.build().append(Restrictions.eq("originalOrderId",orderId))
                .append(Restrictions.eq("type",orderType))
                .order(Order.desc("createTimeStamp"));
        StockRecord stockRecord = stockRecordReadRepository.getOne(wrapper);
        BigDecimal price = BigDecimal.ZERO;
        for (StockRecordItem item: stockRecord.getItems()) {
            if (item.getOrderItemId().equals(orderItemId)) {
                price = item.getPrice();
                break;
            }
        }
        return price;
    }

    /**
     * 出入库单号id
     */
    private Long recordOrderId;
    /**
     * 来源单号itemId
     */
    private Long orderItemId;
    /**
     * 来源单类型
     */
    private Short orderType;
    /**
     * 商品编码
     */
    private String goodsCode;
    /**
     * 所属种类,应用分类编码
     */
    private String categoryCatalogCode;
    /**
     * 商品ID
     */
    private Long goodsId;
    /**
     * 商品名称
     */
    private String goodsName;
    /**
     * 分类id
     */
    private Long categoryId;
    /**
     * 所属分类名称
     */
    private String categoryName;
    /**
     * 品牌id
     */
    private Long goodsBrandId;
    /**
     * 品牌名称
     */
    private String goodsBrandName;
    /**
     * 入库数量
     */
    private BigDecimal quantity;
    /**
     * 商品单价
     */
    private BigDecimal price;
    /**
     * 默认销售税率
     */
    private BigDecimal salesTaxRate;
    /**
     * 纳税人类型: 1：一般纳税人 2：小规模纳税人
     */
    private Short taxpayer;
    /**
     * 规格
     */
    private String specName;
    /**
     * 计量单位
     */
    private String units;
    /**
     * 与基础商品转换率（如果是基础商品 则等于1）
     */
    private BigDecimal conversionRate;
}
